package cfca.httpclient;

import java.net.HttpURLConnection;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Map.Entry;

import com.cmbc.connect.ConnectException;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lmw
 */
@Slf4j
public class CmbcHttpClient {
    public int connectTimeout = 10 * 1000;

    public int readTimeout = 20 * 1000;

    public boolean isSSL = true;

    private CmbcHttpConnection httpConnection;

    public void init(String keyStorePath, String trustStorePath, String keyStorePassword, String trustStorePassword) {
        httpConnection = new CmbcHttpConnection();
        httpConnection.config.connectTimeout = connectTimeout;
        httpConnection.config.readTimeout = readTimeout;
        httpConnection.httpConfig.userAgent = "TrustSign FEP";
        httpConnection.httpConfig.contentType = MIMEType.FORM;
        httpConnection.httpConfig.accept = MIMEType.JSON;

        try {
            if (isSSL) {
                httpConnection.initSSL(keyStorePath, keyStorePassword.toCharArray(), trustStorePath, trustStorePassword.toCharArray());
            }
        } catch (Throwable e) {
            log.error("#39 init error, e=" + e, e);
        }
    }

    public String get(String url, String data) {
        return this.request(url, "GET", null);
    }

    public String get(String url, String data, Map<String, String> map) {
        return this.request(url, "GET", null);
    }

    public String post(String url, String data) {
        return this.request(url, "POST", data);
    }

    public String post(String url, String data, Map<String, String> map) {
        return this.request(url, "POST", this.prepareRequestBody(data, map));
    }

    private String prepareRequestBody(String data, Map<String, String> map) {
        try {
            StringBuilder requestBodyBuilder = new StringBuilder();
            String encodedData = URLEncoder.encode(data, CmbcUtil.DEFAULT_CHARSET);
            requestBodyBuilder.append(encodedData);
            if (CmbcUtil.isNotEmpty(map)) {
                for (Entry<String, String> pair : map.entrySet()) {
                    String val = pair.getValue() == null ? "" : URLEncoder.encode(pair.getValue(), CmbcUtil.DEFAULT_CHARSET);

                    requestBodyBuilder.append("&") //
                            .append(pair.getKey()) //
                            .append("=") //
                            .append(val);
                }
            }
            return requestBodyBuilder.toString();
        } catch (Throwable e) {
            log.error("#72 prepare error, e=" + e, e);
            return null;
        }
    }

    private String request(String url, String method, String request) {
        HttpURLConnection connection = null;
        try {
            connection = httpConnection.connect(url, method);
            httpConnection.writeRequestData(connection, request == null ? null : CmbcUtil.getBytes(request));
            return CmbcUtil.getString(httpConnection.readResponse(connection));
        } catch (Throwable e) {
            log.error("#81 request error, e=" + e, e);
            throw new ConnectException(e);
        } finally {
            httpConnection.disconnect(connection);
        }
    }
}
